const { createClient } = require("redis");
const WinexBedGenerator = require("./WinexBedGenerator");
const WinexRoomGenerator = require("./WinexRoomGenerator");
const WinexWardGenerator = require("./WinexWardGenerator");

class WinexInpatientBaseGenerator {

    constructor(redisHost = "127.0.0.1", redisPort = 6379, redisDb = 0) {
        this.winexBedGenerator = new WinexBedGenerator();
        this.winexRoomGenerator = new WinexRoomGenerator();
        this.winexWardGenerator = new WinexWardGenerator();
        this.redisHost = redisHost;
        this.redisPort = redisPort;
        this.redisDb = redisDb;
    }

    async generate(wardNamePrefix, numberOfWards, numberOfRooms, numberOfbeds) {

        // 创建病区
        let wards = await this.winexWardGenerator.getWards();
        wards = wards.filter(ward => ward.wardName.startsWith(wardNamePrefix));
        wards = await this.winexWardGenerator.update(wards, "新增");
        await this.winexWardGenerator.delete(wards);
        wards = await this.winexWardGenerator.create(numberOfWards, wardNamePrefix);
        let employees = await this.winexWardGenerator.getEmployees();
        let departments = [];
        for (const employee of employees) {
            let tempDepartments = await this.winexWardGenerator.getDepartmentsByEmployee(employee);
            departments.push(...tempDepartments);
        }
        wards = await this.winexWardGenerator.update(wards, "启用", employees);
        for (const ward of wards) {
            await this.winexWardGenerator.setDepartments(ward, departments);
        }
        // 创建房间和床位
        const department = departments[0];
        const client = await createClient({ host: this.redisHost, port: this.redisPort }).on("error", () => { }).connect();
        await client.select(this.redisDb);
        await client.del("inpatientBeds");
        for (const ward of wards) {
            let rooms = await this.winexRoomGenerator.create(ward, numberOfRooms);
            let beds = await this.winexBedGenerator.create(ward, numberOfbeds, "", department);
            await this.winexBedGenerator.setBedChargeServices(ward);
            // 写入Redis
            for (const bed of beds) {
                bed.roomNumber = rooms.find(room => room.roomId === bed.roomId).roomNumber;
                await client.rPush("inpatientBeds", JSON.stringify(bed));
            }
        }
        await client.disconnect();
    }
    async clean(wardNamePrefix) {
        let wards = await this.winexWardGenerator.getWards();
        wards = wards.filter(ward => ward.wardName.startsWith(wardNamePrefix));
        while (wards.length !== 0) {
            await this.winexWardGenerator.update(wards, "新增");
            await this.winexWardGenerator.delete(wards);
            wards = await this.winexWardGenerator.getWards();
            wards = wards.filter(ward => ward.wardName.startsWith(wardNamePrefix));
        }
        const client = await createClient({ host: this.redisHost, port: this.redisPort }).on("error", () => { }).connect();
        await client.select(this.redisDb);
        await client.del("inpatientBeds");
        await client.disconnect();
    }
}

module.exports = WinexInpatientBaseGenerator;